//
//  YWEwinDBManager.m
//  maintain
//
//  Created by Kyo on 16/9/12.
//  Copyright © 2016年 ewin. All rights reserved.
//

#import "YWEwinDBManager.h"
#import "YWDBTool.h"
#import "YWCommonTool.h"

#import "YWEwinMenu.h"
#import "YWLastReadTime.h"
#import "YWEwinManager.h"
#import "YWUnReadCount.h"

@implementation YWEwinDBManager
YWSingletonM(Manager)

- (FMDatabase*)fmdb{
    return [[YWDBTool shareDBTool] fmdb];
}

- (FMDatabaseQueue*)dbQeue{
    return [[YWDBTool shareDBTool] dbQeue];
}

- (NSMutableArray*)defauleMenuArray{
    NSMutableArray *defaultMenu = [[NSMutableArray alloc] init];
    NSArray *nameArr = @[@"notice",@"work_task",@"report_malfunction",@"keep_watch",@"inspection",@"detection",@"upkeep",@"repair",@"meter_reading",@"attendance",@"contacts",@"repository",@"material"];
    NSArray *enNameArr = @[@"notice",@"work_task",@"report_malfunction",@"keep_watch",@"inspection",@"detection",@"upkeep",@"repair",@"meter",@"attendance",@"contacts",@"repository",@"material"];
    NSArray *iconArr = @[@"notice",@"work_task",@"report_malfunction",@"keep_watch",@"inspection",@"detection",@"upkeep",@"repair",@"shuidianmei",@"attendance",@"contacts",@"repository",@"material"];
    
    NSArray *subNameArr = @[@"create_work_task",@"check_inspection_record",@"check_keep_watch_record",@"custom_report_malfunction",@"create_material_apply"];
    NSArray *subEnNameArr = @[@"work_task",@"inspection",@"keep_watch",@"report_malfunction",@"material"];
    NSArray *subIconArr = @[@"create_work_task",@"record",@"record",@"custom_report_malfunction",@"create_material_apply"];
    NSArray *parentId = @[@"100001",@"100004",@"100003",@"100002",@"100012",];
    for (int i = 0; i< nameArr.count; i++) {
        YWEwinMenu *menu = [[YWEwinMenu alloc] init];
        menu.menuId = 100000 + i;
        menu.menuName = nameArr[i];
        menu.enName = enNameArr[i];
        menu.menuIcon = [NSString stringWithFormat:@"menu_%@",iconArr[i]];
        menu.sort = i+1;
        menu.parentMenuId = 0;
        menu.menuURL = @"";
        [defaultMenu addObject:menu];
    }
    for (int i = 0; i< subNameArr.count; i++) {
        YWEwinMenu *menu = [[YWEwinMenu alloc] init];
        menu.menuId = 110000 + i;
        menu.menuName = subNameArr[i];
        menu.enName = subEnNameArr[i];
        menu.menuIcon = [NSString stringWithFormat:@"menu_%@",subIconArr[i]];
        menu.sort = ((i==1 || i == 2) ? 2: 0);
        menu.parentMenuId = [parentId[i] integerValue];
        menu.menuURL = @"";
        [defaultMenu addObject:menu];
    }
    return defaultMenu;
}

NSString *const KSqlCreateMenuTable = @"CREATE TABLE IF NOT EXISTS 'ewin_menu' (menuId integer NOT NULL UNIQUE,menuName varchar,enName varchar,menuIcon varchar,sort integer,parentMenuId integer,menuURL varchar);";

- (void)createEwinMenuTable{
    [self createMenuTable];
}

- (BOOL)createMenuTable{
    return [[self fmdb] executeUpdate:KSqlCreateMenuTable];
}

- (BOOL)saveEwinMenuWithArray:(NSArray*)menuArray{
    __block BOOL executeResult = YES;
    __block NSMutableArray* blockMenus = nil;
    if (menuArray.count) {
        blockMenus = [NSMutableArray array];
        [blockMenus addObjectsFromArray:menuArray];
        [blockMenus addObjectsFromArray:self.defauleMenuArray];
    }
    
    [self.dbQeue inTransaction:^(FMDatabase* db, BOOL* rollback) {
        //服务端关掉的权限不过来，更新时候先删掉再更新
        NSString* sql = @"DELETE FROM 'ewin_menu'";
        executeResult = [db executeUpdate:sql];
        //更新
        [blockMenus enumerateObjectsUsingBlock:^(YWEwinMenu* _Nonnull menu, NSUInteger idx, BOOL* _Nonnull stop) {
            NSString* sql = @"SELECT  * FROM 'ewin_menu' WHERE menuId=?";
            FMResultSet* set = [db executeQuery:sql, @(menu.menuId)];
            if ([set next]) {
                sql = @"UPDATE 'ewin_menu' SET menuName=?, enName=?, menuIcon=?, sort =?,parentMenuId =?,menuURL =? WHERE menuId = ?;";
                executeResult = [db executeUpdate:sql, menu.menuName,menu.enName,menu.menuIcon,@(menu.sort),@(menu.parentMenuId),menu.menuURL,@(menu.menuId)];
            }else {
                sql = @"INSERT INTO 'ewin_menu' (menuId,menuName,enName,menuIcon,sort,parentMenuId,menuURL) VALUES (?, ?, ?, ?, ?,?,?);";
                executeResult = [db executeUpdate:sql, @(menu.menuId),menu.menuName,menu.enName,menu.menuIcon,@(menu.sort),@(menu.parentMenuId),menu.menuURL];
            }
            if (!executeResult) {
                *stop = YES;
                *rollback = YES;
            };
        }];
        [db closeOpenResultSets];
    }];
    return executeResult;
}

- (NSArray*)ewinMenuWithMenuEnName:(NSString*)enName{
    __block NSMutableArray* menuArray = [NSMutableArray array];
    [self.dbQeue inDatabase:^(FMDatabase* db) {
        NSString* sql = @"SELECT * FROM 'ewin_menu' WHERE enName =? AND parentMenuId!=0 ORDER BY sort DESC";
        FMResultSet* set = [db executeQuery:sql,enName];
        while ([set next]) {
            YWEwinMenu* menu = [self ewinMenWithFMResultSet:set FMDatabase:db];
            [menuArray addObject:menu];
        }
        [db closeOpenResultSets];
    }];
    return menuArray;
}

- (YWEwinMenu*)ewinMenWithFMResultSet:(FMResultSet*)set FMDatabase:(FMDatabase*)db{
    YWEwinMenu *ewinMenu = [[YWEwinMenu alloc] init];
    ewinMenu.menuId = [set intForColumn:@"menuId"];
    ewinMenu.menuName = [set stringForColumn:@"menuName"];
    ewinMenu.enName = [set stringForColumn:@"enName"];
    ewinMenu.menuIcon = [set stringForColumn:@"menuIcon"];
    ewinMenu.sort = [set intForColumn:@"sort"];
    ewinMenu.parentMenuId = [set intForColumn:@"parentMenuId"];
    ewinMenu.menuURL = [set stringForColumn:@"menuURL"];
    return ewinMenu;
}

NSString *const KSqlCreateLastReadTimeTable = @"CREATE TABLE IF NOT EXISTS 'ewin_lastReadTime' (noticeTime timestamp,taskTime timestamp,troubleTime timestamp,fixTroubleTime timestamp,inspectionTime timestamp,keepWatchTime timestamp,upkeepTime timestamp,detectionTime timestamp,materialTime timestamp,remindTime timestamp,monitorAlarmTime timestamp);";

- (void)createLastReadTimeTable{
    [[self fmdb] executeUpdate:KSqlCreateLastReadTimeTable];
    NSString *sql = @"INSERT INTO 'ewin_lastReadTime' (noticeTime,taskTime,troubleTime,fixTroubleTime,inspectionTime,keepWatchTime,upkeepTime,detectionTime,materialTime,remindTime,monitorAlarmTime) VALUES (?,?,?,?,?,?,?,?,?,?,?)";
    [[self fmdb] executeUpdate:sql,@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0)];
}

- (BOOL)saveLastReadTime:(NSTimeInterval)lastReadTime type:(NSInteger)unReadType{
    __block BOOL executeResult = YES;
    __block NSString* sql = nil;
    [self.dbQeue inTransaction:^(FMDatabase* db, BOOL* rollback) {
        switch (unReadType) {
            case YWUnReadCountTypeNotice:
                sql = @"UPDATE 'ewin_lastReadTime' SET noticeTime=?";
                break;
            case YWUnReadCountTypeTask:
                sql = @"UPDATE 'ewin_lastReadTime' SET taskTime=?";
                break;
            case YWUnReadCountTypeTrouble:
                sql = @"UPDATE 'ewin_lastReadTime' SET troubleTime=?";
                break;
            case YWUnReadCountTypeFixTrouble:
                sql = @"UPDATE 'ewin_lastReadTime' SET fixTroubleTime=?";
                break;
            case YWUnReadCountTypeInspection:
                sql = @"UPDATE 'ewin_lastReadTime' SET inspectionTime=?";
                break;
            case YWUnReadCountTypeKeepWatch:
                sql = @"UPDATE 'ewin_lastReadTime' SET keepWatchTime=?";
                break;
            case YWUnReadCountTypeUpkeep:
                sql = @"UPDATE 'ewin_lastReadTime' SET upkeepTime=?";
                break;
            case YWUnReadCountTypeDetection:
                sql = @"UPDATE 'ewin_lastReadTime' SET detectionTime=?";
                break;
            case YWUnReadCountTypeMaterial:
                sql = @"UPDATE 'ewin_lastReadTime' SET materialTime=?";
                break;
            case YWUnReadCountTypeRemind:
                sql = @"UPDATE 'ewin_lastReadTime' SET remindTime=?";
                break;
            case YWUnReadCountTypeMonitorAlarm:
                sql = @"UPDATE 'ewin_lastReadTime' SET monitorAlarmTime=?";
                break;
            default:
                break;
        }
        executeResult = [db executeUpdate:sql, @(lastReadTime)];
        if (!executeResult) {
            *rollback = YES;
        };
        [db closeOpenResultSets];
    }];
    return executeResult;
}

- (BOOL)saveLastReadTime:(YWLastReadTime*)lastReadTime{
    __block BOOL executeResult = YES;
    [self.dbQeue inTransaction:^(FMDatabase* db, BOOL* rollback) {
        NSString* sql = @"UPDATE 'ewin_lastReadTime' SET noticeTime=?,taskTime=?,troubleTime=?,fixTroubleTime=?,inspectionTime=?,keepWatchTime=?,upkeepTime=?,detectionTime=?,materialTime=?,remindTime=?,monitorAlarmTime=?";
        executeResult = [db executeUpdate:sql, @(lastReadTime.noticeTime),@(lastReadTime.taskTime),@(lastReadTime.troubleTime),@(lastReadTime.fixTroubleTime),@(lastReadTime.inspectionTime),@(lastReadTime.keepWatchTime),@(lastReadTime.upkeepTime),@(lastReadTime.detectionTime),@(lastReadTime.materialTime),@(lastReadTime.remindTime),@(lastReadTime.monitorAlarmTime)];
        if (!executeResult) {
            *rollback = YES;
        };
        [db closeOpenResultSets];
    }];
    return executeResult;
}

- (YWLastReadTime*)lastReadTime{
    __block YWLastReadTime* lastReadTime = nil;
    [self.dbQeue inDatabase:^(FMDatabase* db) {
        NSString* sql = @"SELECT * FROM 'ewin_lastReadTime'";
        FMResultSet* set = [db executeQuery:sql];
        if ([set next]) {
            lastReadTime = [self lastReadTimeWithFMResultSet:set FMDatabase:db];
        }
        [db closeOpenResultSets];
    }];
    return lastReadTime;
}

- (YWLastReadTime*)lastReadTimeWithFMResultSet:(FMResultSet*)set FMDatabase:(FMDatabase*)db{
    YWLastReadTime *lastReadTime = [[YWLastReadTime alloc] init];
    lastReadTime.noticeTime = [set longLongIntForColumn:@"noticeTime"];
    lastReadTime.taskTime = [set longLongIntForColumn:@"taskTime"];
    lastReadTime.troubleTime = [set longLongIntForColumn:@"troubleTime"];
    lastReadTime.fixTroubleTime = [set longLongIntForColumn:@"fixTroubleTime"];
    lastReadTime.inspectionTime = [set longLongIntForColumn:@"inspectionTime"];
    lastReadTime.keepWatchTime = [set longLongIntForColumn:@"keepWatchTime"];
    lastReadTime.upkeepTime = [set longLongIntForColumn:@"upkeepTime"];
    lastReadTime.detectionTime = [set longLongIntForColumn:@"detectionTime"];
    lastReadTime.materialTime = [set longLongIntForColumn:@"materialTime"];
    lastReadTime.remindTime = [set longLongIntForColumn:@"remindTime"];
    lastReadTime.monitorAlarmTime = [set longLongIntForColumn:@"monitorAlarmTime"];
    return lastReadTime;
}

NSString *const KSqlCreateTotalCountTable = @"CREATE TABLE IF NOT EXISTS 'ewin_totalCount' (noticeTotal integer,taskTotal integer,troubleTotal integer,fixTroubleTotal integer,inspectionTotal integer,keepWatchTotal integer,upkeepTotal integer,detectionTotal integer,materialTotal integer,unDistributionTroubleTotal integer);";

- (void)createTotalCountTable{
    [[self fmdb] executeUpdate:KSqlCreateTotalCountTable];
    NSString *sql = @"INSERT INTO 'ewin_totalCount' (noticeTotal,taskTotal,troubleTotal,fixTroubleTotal,inspectionTotal,keepWatchTotal,upkeepTotal,detectionTotal,materialTotal,unDistributionTroubleTotal) VALUES (?,?,?,?,?,?,?,?,?,?)";
    [[self fmdb] executeUpdate:sql,@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0),@(0)];
}

- (BOOL)updateTotalCount:(YWUnReadCount*)unreadCount{
    if (unreadCount==nil) {
        return YES;
    }
    __block BOOL executeResult = YES;
    [self.dbQeue inTransaction:^(FMDatabase* db, BOOL* rollback) {
        NSString* sql = @"UPDATE 'ewin_totalCount' SET noticeTotal=?,taskTotal=?,troubleTotal=?,fixTroubleTotal=?,inspectionTotal=?,keepWatchTotal=?,upkeepTotal=?,detectionTotal=?,materialTotal=?,unDistributionTroubleTotal=?";
        executeResult = [db executeUpdate:sql, @(unreadCount.noticeTotal),@(unreadCount.taskTotal),@(unreadCount.troubleTotal),@(unreadCount.fixTroubleTotal),@(unreadCount.inspectionTotal),@(unreadCount.keepWatchTotal),@(unreadCount.upkeepTotal),@(unreadCount.detectionTotal),@(unreadCount.materialTotal),@(unreadCount.unDistributionTroubleTotal)];
        if (!executeResult) {
            *rollback = YES;
        };
        [db closeOpenResultSets];
    }];
    return executeResult;
}

- (YWUnReadCount*)totalCount{
    __block YWUnReadCount* totalCount = nil;
    [self.dbQeue inDatabase:^(FMDatabase* db) {
        NSString* sql = @"SELECT * FROM 'ewin_totalCount'";
        FMResultSet* set = [db executeQuery:sql];
        if ([set next]) {
            totalCount = [self totalCountWithFMResultSet:set FMDatabase:db];
        }
        [db closeOpenResultSets];
    }];
    return totalCount;
}

- (YWUnReadCount*)totalCountWithFMResultSet:(FMResultSet*)set FMDatabase:(FMDatabase*)db{
    YWUnReadCount *totalCount = [[YWUnReadCount alloc] init];
    totalCount.noticeTotal = [set intForColumn:@"noticeTotal"];
    totalCount.taskTotal = [set intForColumn:@"taskTotal"];
    totalCount.troubleTotal = [set intForColumn:@"troubleTotal"];
    totalCount.fixTroubleTotal = [set intForColumn:@"fixTroubleTotal"];
    totalCount.inspectionTotal = [set intForColumn:@"inspectionTotal"];
    totalCount.keepWatchTotal = [set intForColumn:@"keepWatchTotal"];
    totalCount.upkeepTotal = [set intForColumn:@"upkeepTotal"];
    totalCount.detectionTotal = [set intForColumn:@"detectionTotal"];
    totalCount.materialTotal = [set intForColumn:@"materialTotal"];
    totalCount.unDistributionTroubleTotal = [set intForColumn:@"unDistributionTroubleTotal"];
    return totalCount;
}

- (void)addTotalCountWithType:(NSInteger)unReadType{
    [self addOrSubtractTotalCount:YES type:unReadType];
}

- (void)subtractTotalCountWithType:(NSInteger)unReadType{
    [self addOrSubtractTotalCount:NO type:unReadType];
}

- (void)addOrSubtractTotalCount:(BOOL)add type:(NSInteger)unReadType{
    YWUnReadCount *unreadCount = [self totalCount];
    if (unReadType == YWUnReadCountTypeNotice) {
        if (add) {
            unreadCount.noticeTotal++;
        }else{
            unreadCount.noticeTotal--;
            if (unreadCount.noticeTotal<0) {
                unreadCount.noticeTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeTask){
        if (add) {
            unreadCount.taskTotal++;
        }else{
            unreadCount.taskTotal--;
            if (unreadCount.taskTotal<0) {
                unreadCount.taskTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeTrouble){
        if (add) {
            unreadCount.troubleTotal++;
        }else{
            unreadCount.troubleTotal--;
            if (unreadCount.troubleTotal<0) {
                unreadCount.troubleTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeFixTrouble){
        if (add) {
            unreadCount.fixTroubleTotal++;
        }else{
            unreadCount.fixTroubleTotal--;
            if (unreadCount.fixTroubleTotal<0) {
                unreadCount.fixTroubleTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeInspection){
        if (add) {
            unreadCount.inspectionTotal++;
        }else{
            unreadCount.inspectionTotal--;
            if (unreadCount.inspectionTotal<0) {
                unreadCount.inspectionTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeKeepWatch){
        if (add) {
            unreadCount.keepWatchTotal++;
        }else{
            unreadCount.keepWatchTotal--;
            if (unreadCount.keepWatchTotal<0) {
                unreadCount.keepWatchTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeUpkeep){
        if (add) {
            unreadCount.upkeepTotal++;
        }else{
            unreadCount.upkeepTotal--;
            if (unreadCount.upkeepTotal<0) {
                unreadCount.upkeepTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeDetection){
        if (add) {
            unreadCount.detectionTotal++;
        }else{
            unreadCount.detectionTotal--;
            if (unreadCount.detectionTotal<0) {
                unreadCount.detectionTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeMaterial){
        if (add) {
            unreadCount.materialTotal++;
        }else{
            unreadCount.materialTotal--;
            if (unreadCount.materialTotal<0) {
                unreadCount.materialTotal = 0;
            }
        }
    }else if (unReadType == YWUnReadCountTypeUnDistributionTroubleTotal){
        if (add) {
            unreadCount.unDistributionTroubleTotal++;
        }else{
            unreadCount.unDistributionTroubleTotal--;
            if (unreadCount.unDistributionTroubleTotal<0) {
                unreadCount.unDistributionTroubleTotal = 0;
            }
        }
    }
    [self updateTotalCount:unreadCount];
}


@end
